/**
 * 
 */
package org.mhz.sit.logging;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;

/**
 * @author Mahan
 *
 * Logging interceptor class
 */
public class LoggingInterceptor
{
    @Pointcut("execution(public * *(..))")
    private void anyPublicOperation() { }    
    
    @Pointcut("within(org.mhz.sit.service..*)")
    public void inServiceLayer() { }
    
    @Pointcut("within(org.mhz.sit.dataaccess..*)")
    public void inDataAccessLayer() { }
    
    /**
     * Log the time taken for a method
     *
     * @param aProceedingJoinPoint - The proceeding join point
     * @throws Throwable
     */
    @Around("anyPublicOperation() && @annotation(org.mhz.sit.annotation.LogTimeTaken)")
    public Object logTimeTaken(final ProceedingJoinPoint aProceedingJoinPoint) throws Throwable
    {       
        final String nameOfClass = aProceedingJoinPoint.getTarget().toString();
        final Logger logger = LoggerFactory.getLogger(nameOfClass);
        
        final String shortDescr = aProceedingJoinPoint.toShortString();
        final String nameOfMethod = aProceedingJoinPoint.getSignature().getName();
        
        final StopWatch sw = new StopWatch();
        
        // Start the stopwatch
        sw.start(nameOfMethod);

        // Invoke method
        final Object retVal = aProceedingJoinPoint.proceed();
        
        // Stop the stopwatch
        sw.stop();
        
        logger.info("{} took {}ms", new Object[] {shortDescr, sw.getTotalTimeMillis()});
        
        return retVal;
    }
}
